import xml.etree.ElementTree as ET
from datetime import datetime
from PyQt5.QtWidgets import QFileDialog
from rss_reader.logger import logger
from rss_reader.database.models import Feed, Article
import feedparser


def export_feeds_to_opml(session, parent_widget=None):
    """导出用户的订阅列表到OPML文件"""
    try:
        feeds = session.query(Feed).all()
        if not feeds:
            logger.warning("没有订阅可导出")
            return False

        filename, _ = QFileDialog.getSaveFileName(
            parent_widget,
            "导出OPML文件",
            "",
            "OPML Files (*.opml);;All Files (*)"
        )
        if not filename:
            logger.debug("用户取消导出操作")
            return False

        opml = ET.Element('opml', version='1.0')
        head = ET.SubElement(opml, 'head')
        ET.SubElement(head, 'title').text = f"RSS订阅导出 - {datetime.now().strftime('%Y-%m-%d')}"
        ET.SubElement(head, 'dateCreated').text = datetime.now().isoformat()

        body = ET.SubElement(opml, 'body')
        categories = {}

        for feed in feeds:
            # 使用字典存储父节点引用
            if feed.category not in categories:
                category = ET.SubElement(body, 'outline', {'text': feed.category})
                categories[feed.category] = category

            ET.SubElement(categories[feed.category], 'outline', {
                'type': 'rss',
                'text': feed.title,
                'title': feed.title,
                'xmlUrl': feed.url
            })

        ET.indent(opml)  # 美化XML输出
        tree = ET.ElementTree(opml)
        tree.write(filename, encoding='utf-8', xml_declaration=True)
        logger.info(f"成功导出OPML文件到: {filename}")
        return True

    except Exception as e:
        logger.error(f"导出OPML失败: {str(e)}", exc_info=True)
        return False


def import_feeds_from_opml(session, parent_widget=None):
    """从OPML文件导入订阅"""
    try:
        filename, _ = QFileDialog.getOpenFileName(
            parent_widget,
            "导入OPML文件",
            "",
            "OPML Files (*.opml);;All Files (*)"
        )
        if not filename:
            logger.debug("用户取消导入操作")
            return 0

        tree = ET.parse(filename)
        root = tree.getroot()

        imported_count = 0
        categories = {}  # 存储分类关系

        # 第一遍：建立分类结构
        for outline in root.findall('.//outline'):
            if outline.get('xmlUrl'):  # 这是订阅项
                parent = outline
                while (parent := parent.find('..')) is not None:  # 向上查找父级
                    if parent.get('text') and not parent.get('xmlUrl'):
                        category = parent.get('text')
                        break
                else:
                    category = '未分类'

                categories[outline] = category

        # 第二遍：导入订阅
        for outline, category in categories.items():
            title = outline.get('text') or outline.get('title') or '未命名订阅'
            url = outline.get('xmlUrl')

            if not url:
                continue

            existing = session.query(Feed).filter_by(url=url).first()
            if not existing:
                parsed = feedparser.parse(url)
                icon_url = parsed.feed.get('icon') or parsed.feed.get('image', {}).get('href')
                feed = Feed(
                    title=title,
                    url=url,
                    icon_url=icon_url,
                    category=category,
                )
                session.add(feed)
                imported_count += 1

        session.commit()
        logger.info(f"成功从 {filename} 导入 {imported_count} 个订阅")
        return imported_count

    except ET.ParseError as e:
        logger.error(f"OPML文件解析失败: {str(e)}")
        return False
    except Exception as e:
        session.rollback()
        logger.error(f"导入OPML失败: {str(e)}", exc_info=True)
        return False